"""Problem Detection Modules.

Provides various problem detectors for network, hardware, software,
and configuration issues.
"""

import asyncio
import aiohttp
import json
import logging
import psutil
import time
from abc import ABC, abstractmethod
from datetime import datetime, timedelta
from typing import Dict, List, Optional, Any
from dataclasses import dataclass

from .diagnostic_engine import DetectedProblem, ProblemType, SeverityLevel

logger = logging.getLogger(__name__)


class ProblemDetector(ABC):
    """Base class for problem detectors."""
    
    def __init__(self, name: str, config: Dict[str, Any]):
        """Initialize detector.
        
        Args:
            name: Detector name
            config: Detector configuration
        """
        self.name = name
        self.config = config
        self.enabled = config.get("enabled", True)
        self.check_interval = config.get("check_interval", 60)
        self.last_check_time: Optional[datetime] = None
        
        # Detection history
        self.detection_history: List[DetectedProblem] = []
        self.max_history = 100
        
        logger.info(f"Initialized detector: {self.name}")
    
    @abstractmethod
    async def detect_problems(self, device_context: Dict[str, Any]) -> List[DetectedProblem]:
        """Detect problems for the given device context.
        
        Args:
            device_context: Context information about the device
            
        Returns:
            List of detected problems
        """
        pass
    
    def should_check(self) -> bool:
        """Check if detector should run based on interval."""
        if not self.enabled:
            return False
            
        if self.last_check_time is None:
            return True
            
        return (datetime.now() - self.last_check_time).total_seconds() >= self.check_interval
    
    def _add_to_history(self, problem: DetectedProblem):
        """Add problem to detection history."""
        self.detection_history.append(problem)
        if len(self.detection_history) > self.max_history:
            self.detection_history.pop(0)
    
    def _create_problem(self, problem_type: ProblemType, severity: SeverityLevel,
                       title: str, description: str, confidence: float,
                       symptom_data: Dict[str, Any], 
                       affected_components: List[str],
                       error_codes: List[str] = None) -> DetectedProblem:
        """Create a DetectedProblem instance."""
        problem = DetectedProblem(
            problem_id=f"{self.name}_{problem_type.value}_{int(time.time())}",
            problem_type=problem_type,
            severity=severity,
            title=title,
            description=description,
            detector_name=self.name,
            detected_at=datetime.now(),
            confidence=confidence,
            symptom_data=symptom_data,
            affected_components=affected_components,
            error_codes=error_codes or []
        )
        
        # Check historical occurrences
        problem.historical_occurrences = len([
            p for p in self.detection_history
            if p.problem_type == problem_type and p.title == title
        ])
        
        self._add_to_history(problem)
        return problem


class NetworkDetector(ProblemDetector):
    """Network connectivity problem detector."""
    
    def __init__(self, config: Dict[str, Any]):
        super().__init__("network_detector", config)
        self.timeout = config.get("timeout", 10)
        self.test_urls = config.get("test_urls", [
            "https://www.google.com",
            "https://1.1.1.1",
            "https://8.8.8.8"
        ])
        self.dns_servers = config.get("dns_servers", ["8.8.8.8", "1.1.1.1"])
        self.ping_targets = config.get("ping_targets", ["8.8.8.8", "1.1.1.1"])
        
        # Network metrics
        self.baseline_latency = 50.0  # ms
        self.max_packet_loss = 5.0    # %
    
    async def detect_problems(self, device_context: Dict[str, Any]) -> List[DetectedProblem]:
        """Detect network problems."""
        self.last_check_time = datetime.now()
        problems = []
        
        try:
            # Check basic connectivity
            connectivity_problem = await self._check_connectivity()
            if connectivity_problem:
                problems.append(connectivity_problem)
            
            # Check DNS resolution
            dns_problem = await self._check_dns_resolution()
            if dns_problem:
                problems.append(dns_problem)
            
            # Check network latency
            latency_problem = await self._check_network_latency()
            if latency_problem:
                problems.append(latency_problem)
            
            # Check network interface status
            interface_problem = await self._check_network_interfaces()
            if interface_problem:
                problems.append(interface_problem)
            
        except Exception as e:
            error_problem = self._create_problem(
                ProblemType.NETWORK_CONNECTIVITY,
                SeverityLevel.CRITICAL,
                "Network detector error",
                f"Error during network detection: {str(e)}",
                0.8,
                {"error": str(e), "detector": self.name},
                ["network_detector"]
            )
            problems.append(error_problem)
        
        logger.debug(f"Network detector found {len(problems)} problems")
        return problems
    
    async def _check_connectivity(self) -> Optional[DetectedProblem]:
        """Check basic internet connectivity."""
        successful_connections = 0
        failed_urls = []
        
        try:
            timeout = aiohttp.ClientTimeout(total=self.timeout)
            async with aiohttp.ClientSession(timeout=timeout) as session:
                for url in self.test_urls:
                    try:
                        async with session.get(url) as response:
                            if response.status == 200:
                                successful_connections += 1
                            else:
                                failed_urls.append(f"{url} (status: {response.status})")
                    except Exception as e:
                        failed_urls.append(f"{url} (error: {str(e)})")
                        
        except Exception as e:
            return self._create_problem(
                ProblemType.NETWORK_CONNECTIVITY,
                SeverityLevel.CRITICAL,
                "Network connectivity check failed",
                f"Unable to test network connectivity: {str(e)}",
                0.9,
                {"error": str(e), "test_urls": self.test_urls},
                ["network_interface", "internet_gateway"]
            )
        
        # Analyze results
        if successful_connections == 0:
            return self._create_problem(
                ProblemType.NETWORK_CONNECTIVITY,
                SeverityLevel.CRITICAL,
                "Complete network connectivity failure",
                f"Unable to reach any of {len(self.test_urls)} test URLs",
                0.95,
                {
                    "failed_urls": failed_urls,
                    "successful_connections": successful_connections,
                    "total_tested": len(self.test_urls)
                },
                ["network_interface", "internet_gateway", "dns"]
            )
        elif successful_connections < len(self.test_urls) * 0.5:
            return self._create_problem(
                ProblemType.NETWORK_CONNECTIVITY,
                SeverityLevel.HIGH,
                "Partial network connectivity issues",
                f"Only {successful_connections}/{len(self.test_urls)} connectivity tests passed",
                0.8,
                {
                    "failed_urls": failed_urls,
                    "successful_connections": successful_connections,
                    "total_tested": len(self.test_urls)
                },
                ["network_interface", "internet_gateway"]
            )
        
        return None
    
    async def _check_dns_resolution(self) -> Optional[DetectedProblem]:
        """Check DNS resolution."""
        test_domains = ["google.com", "cloudflare.com", "github.com"]
        failed_resolutions = []
        
        try:
            for domain in test_domains:
                try:
                    # Use aiohttp's built-in DNS resolution
                    timeout = aiohttp.ClientTimeout(total=5)
                    async with aiohttp.ClientSession(timeout=timeout) as session:
                        async with session.get(f"https://{domain}", 
                                             allow_redirects=False) as response:
                            pass  # We just want to test DNS resolution
                except aiohttp.ClientError as e:
                    if "name or service not known" in str(e).lower():
                        failed_resolutions.append(domain)
                except Exception:
                    # Other errors (like connection refused) indicate DNS worked
                    pass
                    
        except Exception as e:
            return self._create_problem(
                ProblemType.NETWORK_CONNECTIVITY,
                SeverityLevel.HIGH,
                "DNS resolution test failed",
                f"Unable to test DNS resolution: {str(e)}",
                0.7,
                {"error": str(e)},
                ["dns"]
            )
        
        if len(failed_resolutions) >= len(test_domains) * 0.5:
            return self._create_problem(
                ProblemType.NETWORK_CONNECTIVITY,
                SeverityLevel.HIGH,
                "DNS resolution issues",
                f"Failed to resolve {len(failed_resolutions)}/{len(test_domains)} test domains",
                0.85,
                {
                    "failed_domains": failed_resolutions,
                    "dns_servers": self.dns_servers
                },
                ["dns", "network_configuration"]
            )
        
        return None
    
    async def _check_network_latency(self) -> Optional[DetectedProblem]:
        """Check network latency using HTTP requests as a proxy."""
        latencies = []
        
        try:
            timeout = aiohttp.ClientTimeout(total=self.timeout)
            async with aiohttp.ClientSession(timeout=timeout) as session:
                for url in self.test_urls[:2]:  # Test fewer URLs for latency
                    try:
                        start_time = time.time()
                        async with session.get(url) as response:
                            latency = (time.time() - start_time) * 1000  # Convert to ms
                            latencies.append(latency)
                    except Exception:
                        # Timeout or error indicates high latency
                        latencies.append(self.timeout * 1000)
                        
        except Exception as e:
            return self._create_problem(
                ProblemType.PERFORMANCE_DEGRADATION,
                SeverityLevel.MEDIUM,
                "Network latency test failed",
                f"Unable to measure network latency: {str(e)}",
                0.6,
                {"error": str(e)},
                ["network_interface"]
            )
        
        if latencies:
            avg_latency = sum(latencies) / len(latencies)
            max_latency = max(latencies)
            
            if avg_latency > self.baseline_latency * 3:  # 3x baseline
                return self._create_problem(
                    ProblemType.PERFORMANCE_DEGRADATION,
                    SeverityLevel.HIGH if avg_latency > self.baseline_latency * 5 else SeverityLevel.MEDIUM,
                    "High network latency detected",
                    f"Average latency {avg_latency:.1f}ms exceeds baseline {self.baseline_latency}ms",
                    0.8,
                    {
                        "average_latency": avg_latency,
                        "max_latency": max_latency,
                        "baseline_latency": self.baseline_latency,
                        "measurements": latencies
                    },
                    ["network_interface", "internet_gateway"]
                )
        
        return None
    
    async def _check_network_interfaces(self) -> Optional[DetectedProblem]:
        """Check network interface status."""
        try:
            interfaces = psutil.net_if_stats()
            problematic_interfaces = []
            
            for interface, stats in interfaces.items():
                if interface.startswith(('lo', 'docker')):
                    continue  # Skip loopback and docker interfaces
                    
                if not stats.isup:
                    problematic_interfaces.append(f"{interface} (down)")
            
            if problematic_interfaces:
                return self._create_problem(
                    ProblemType.NETWORK_CONNECTIVITY,
                    SeverityLevel.HIGH,
                    "Network interface issues",
                    f"Network interfaces are down: {', '.join(problematic_interfaces)}",
                    0.9,
                    {
                        "down_interfaces": problematic_interfaces,
                        "all_interfaces": list(interfaces.keys())
                    },
                    ["network_interface"]
                )
                
        except Exception as e:
            return self._create_problem(
                ProblemType.NETWORK_CONNECTIVITY,
                SeverityLevel.MEDIUM,
                "Network interface check failed",
                f"Unable to check network interfaces: {str(e)}",
                0.6,
                {"error": str(e)},
                ["network_interface"]
            )
        
        return None


class HardwareDetector(ProblemDetector):
    """Hardware status problem detector."""
    
    def __init__(self, config: Dict[str, Any]):
        super().__init__("hardware_detector", config)
        self.cpu_threshold = config.get("cpu_threshold", 90)
        self.memory_threshold = config.get("memory_threshold", 85)
        self.disk_threshold = config.get("disk_threshold", 90)
        self.temperature_threshold = config.get("temperature_threshold", 85)
    
    async def detect_problems(self, device_context: Dict[str, Any]) -> List[DetectedProblem]:
        """Detect hardware problems."""
        self.last_check_time = datetime.now()
        problems = []
        
        try:
            # Check CPU usage
            cpu_problem = await self._check_cpu_usage()
            if cpu_problem:
                problems.append(cpu_problem)
            
            # Check memory usage
            memory_problem = await self._check_memory_usage()
            if memory_problem:
                problems.append(memory_problem)
            
            # Check disk usage
            disk_problems = await self._check_disk_usage()
            problems.extend(disk_problems)
            
            # Check system temperature (if available)
            temp_problem = await self._check_system_temperature()
            if temp_problem:
                problems.append(temp_problem)
            
        except Exception as e:
            error_problem = self._create_problem(
                ProblemType.HARDWARE_FAILURE,
                SeverityLevel.MEDIUM,
                "Hardware detector error",
                f"Error during hardware detection: {str(e)}",
                0.7,
                {"error": str(e)},
                ["hardware_detector"]
            )
            problems.append(error_problem)
        
        logger.debug(f"Hardware detector found {len(problems)} problems")
        return problems
    
    async def _check_cpu_usage(self) -> Optional[DetectedProblem]:
        """Check CPU usage."""
        try:
            # Get CPU usage over a short interval
            cpu_percent = psutil.cpu_percent(interval=1)
            cpu_count = psutil.cpu_count()
            
            if cpu_percent > self.cpu_threshold:
                severity = SeverityLevel.CRITICAL if cpu_percent > 95 else SeverityLevel.HIGH
                
                # Get per-CPU statistics
                per_cpu = psutil.cpu_percent(percpu=True)
                
                return self._create_problem(
                    ProblemType.RESOURCE_EXHAUSTION,
                    severity,
                    "High CPU usage detected",
                    f"CPU usage at {cpu_percent:.1f}% exceeds threshold {self.cpu_threshold}%",
                    0.9,
                    {
                        "cpu_percent": cpu_percent,
                        "threshold": self.cpu_threshold,
                        "cpu_count": cpu_count,
                        "per_cpu_usage": per_cpu
                    },
                    ["cpu", "system_performance"]
                )
                
        except Exception as e:
            return self._create_problem(
                ProblemType.HARDWARE_FAILURE,
                SeverityLevel.MEDIUM,
                "CPU monitoring failed",
                f"Unable to check CPU usage: {str(e)}",
                0.6,
                {"error": str(e)},
                ["cpu", "system_monitoring"]
            )
        
        return None
    
    async def _check_memory_usage(self) -> Optional[DetectedProblem]:
        """Check memory usage."""
        try:
            memory = psutil.virtual_memory()
            swap = psutil.swap_memory()
            
            memory_percent = memory.percent
            
            if memory_percent > self.memory_threshold:
                severity = SeverityLevel.CRITICAL if memory_percent > 95 else SeverityLevel.HIGH
                
                return self._create_problem(
                    ProblemType.RESOURCE_EXHAUSTION,
                    severity,
                    "High memory usage detected",
                    f"Memory usage at {memory_percent:.1f}% exceeds threshold {self.memory_threshold}%",
                    0.9,
                    {
                        "memory_percent": memory_percent,
                        "memory_total": memory.total,
                        "memory_available": memory.available,
                        "memory_used": memory.used,
                        "swap_percent": swap.percent,
                        "threshold": self.memory_threshold
                    },
                    ["memory", "system_performance"]
                )
                
        except Exception as e:
            return self._create_problem(
                ProblemType.HARDWARE_FAILURE,
                SeverityLevel.MEDIUM,
                "Memory monitoring failed",
                f"Unable to check memory usage: {str(e)}",
                0.6,
                {"error": str(e)},
                ["memory", "system_monitoring"]
            )
        
        return None
    
    async def _check_disk_usage(self) -> List[DetectedProblem]:
        """Check disk usage for all mounted filesystems."""
        problems = []
        
        try:
            disk_partitions = psutil.disk_partitions()
            
            for partition in disk_partitions:
                try:
                    usage = psutil.disk_usage(partition.mountpoint)
                    usage_percent = (usage.used / usage.total) * 100
                    
                    if usage_percent > self.disk_threshold:
                        severity = SeverityLevel.CRITICAL if usage_percent > 95 else SeverityLevel.HIGH
                        
                        problem = self._create_problem(
                            ProblemType.RESOURCE_EXHAUSTION,
                            severity,
                            f"High disk usage on {partition.mountpoint}",
                            f"Disk usage at {usage_percent:.1f}% exceeds threshold {self.disk_threshold}%",
                            0.9,
                            {
                                "mountpoint": partition.mountpoint,
                                "device": partition.device,
                                "fstype": partition.fstype,
                                "usage_percent": usage_percent,
                                "total_bytes": usage.total,
                                "used_bytes": usage.used,
                                "free_bytes": usage.free,
                                "threshold": self.disk_threshold
                            },
                            ["disk", "filesystem", "storage"]
                        )
                        problems.append(problem)
                        
                except PermissionError:
                    # Skip partitions we can't access
                    continue
                except Exception as e:
                    problem = self._create_problem(
                        ProblemType.HARDWARE_FAILURE,
                        SeverityLevel.MEDIUM,
                        f"Disk monitoring failed for {partition.mountpoint}",
                        f"Unable to check disk usage: {str(e)}",
                        0.6,
                        {"error": str(e), "mountpoint": partition.mountpoint},
                        ["disk", "filesystem"]
                    )
                    problems.append(problem)
                    
        except Exception as e:
            problem = self._create_problem(
                ProblemType.HARDWARE_FAILURE,
                SeverityLevel.MEDIUM,
                "Disk enumeration failed",
                f"Unable to enumerate disk partitions: {str(e)}",
                0.6,
                {"error": str(e)},
                ["disk", "system_monitoring"]
            )
            problems.append(problem)
        
        return problems
    
    async def _check_system_temperature(self) -> Optional[DetectedProblem]:
        """Check system temperature (if available)."""
        try:
            # Try to get temperature sensors
            if hasattr(psutil, "sensors_temperatures"):
                temps = psutil.sensors_temperatures()
                high_temps = []
                
                for sensor_name, sensor_list in temps.items():
                    for sensor in sensor_list:
                        if sensor.current and sensor.current > self.temperature_threshold:
                            high_temps.append({
                                "sensor": f"{sensor_name}.{sensor.label or 'unknown'}",
                                "temperature": sensor.current,
                                "critical": sensor.critical,
                                "high": sensor.high
                            })
                
                if high_temps:
                    max_temp = max(temp["temperature"] for temp in high_temps)
                    severity = SeverityLevel.CRITICAL if max_temp > 90 else SeverityLevel.HIGH
                    
                    return self._create_problem(
                        ProblemType.HARDWARE_FAILURE,
                        severity,
                        "High system temperature detected",
                        f"System temperature {max_temp:.1f}°C exceeds threshold {self.temperature_threshold}°C",
                        0.8,
                        {
                            "high_temperature_sensors": high_temps,
                            "max_temperature": max_temp,
                            "threshold": self.temperature_threshold
                        },
                        ["temperature", "cooling", "hardware"]
                    )
            
        except Exception as e:
            # Temperature monitoring not available or failed - not critical
            logger.debug(f"Temperature monitoring not available: {e}")
        
        return None


class SoftwareDetector(ProblemDetector):
    """Software and service problem detector."""
    
    def __init__(self, config: Dict[str, Any]):
        super().__init__("software_detector", config)
        self.process_monitoring = config.get("process_monitoring", True)
        self.service_monitoring = config.get("service_monitoring", True)
        self.critical_processes = config.get("critical_processes", [])
        self.critical_services = config.get("critical_services", [])
    
    async def detect_problems(self, device_context: Dict[str, Any]) -> List[DetectedProblem]:
        """Detect software problems."""
        self.last_check_time = datetime.now()
        problems = []
        
        try:
            # Check for zombie processes
            zombie_problem = await self._check_zombie_processes()
            if zombie_problem:
                problems.append(zombie_problem)
            
            # Check critical processes
            if self.process_monitoring:
                process_problems = await self._check_critical_processes()
                problems.extend(process_problems)
            
            # Check system load
            load_problem = await self._check_system_load()
            if load_problem:
                problems.append(load_problem)
            
        except Exception as e:
            error_problem = self._create_problem(
                ProblemType.SOFTWARE_ERROR,
                SeverityLevel.MEDIUM,
                "Software detector error",
                f"Error during software detection: {str(e)}",
                0.7,
                {"error": str(e)},
                ["software_detector"]
            )
            problems.append(error_problem)
        
        logger.debug(f"Software detector found {len(problems)} problems")
        return problems
    
    async def _check_zombie_processes(self) -> Optional[DetectedProblem]:
        """Check for zombie processes."""
        try:
            zombie_count = 0
            zombie_pids = []
            
            for proc in psutil.process_iter(['pid', 'status', 'name']):
                if proc.info['status'] == psutil.STATUS_ZOMBIE:
                    zombie_count += 1
                    zombie_pids.append(proc.info['pid'])
            
            if zombie_count > 5:  # Threshold for concern
                severity = SeverityLevel.HIGH if zombie_count > 20 else SeverityLevel.MEDIUM
                
                return self._create_problem(
                    ProblemType.SOFTWARE_ERROR,
                    severity,
                    "High number of zombie processes",
                    f"Found {zombie_count} zombie processes in the system",
                    0.8,
                    {
                        "zombie_count": zombie_count,
                        "zombie_pids": zombie_pids[:10]  # Limit to first 10
                    },
                    ["process_management", "system_health"]
                )
                
        except Exception as e:
            return self._create_problem(
                ProblemType.SOFTWARE_ERROR,
                SeverityLevel.LOW,
                "Process monitoring failed",
                f"Unable to check process status: {str(e)}",
                0.6,
                {"error": str(e)},
                ["process_management"]
            )
        
        return None
    
    async def _check_critical_processes(self) -> List[DetectedProblem]:
        """Check status of critical processes."""
        problems = []
        
        if not self.critical_processes:
            return problems
        
        try:
            running_processes = {proc.info['name']: proc for proc in 
                               psutil.process_iter(['name', 'pid', 'status', 'cpu_percent'])}
            
            for critical_process in self.critical_processes:
                if critical_process not in running_processes:
                    problem = self._create_problem(
                        ProblemType.SERVICE_UNAVAILABLE,
                        SeverityLevel.HIGH,
                        f"Critical process not running: {critical_process}",
                        f"Critical process '{critical_process}' is not currently running",
                        0.9,
                        {
                            "process_name": critical_process,
                            "running_processes": list(running_processes.keys())
                        },
                        ["process_management", "critical_services"]
                    )
                    problems.append(problem)
                    
        except Exception as e:
            problem = self._create_problem(
                ProblemType.SOFTWARE_ERROR,
                SeverityLevel.MEDIUM,
                "Critical process check failed",
                f"Unable to check critical processes: {str(e)}",
                0.7,
                {"error": str(e), "critical_processes": self.critical_processes},
                ["process_management"]
            )
            problems.append(problem)
        
        return problems
    
    async def _check_system_load(self) -> Optional[DetectedProblem]:
        """Check system load average."""
        try:
            # Get load average (1, 5, 15 minutes)
            load_avg = psutil.getloadavg()
            cpu_count = psutil.cpu_count()
            
            # Load average relative to CPU count
            load_1min_ratio = load_avg[0] / cpu_count if cpu_count > 0 else load_avg[0]
            load_5min_ratio = load_avg[1] / cpu_count if cpu_count > 0 else load_avg[1]
            
            # High load if 1-minute load is > 2x CPU count or 5-minute load > 1.5x CPU count
            if load_1min_ratio > 2.0 or load_5min_ratio > 1.5:
                severity = SeverityLevel.HIGH if load_1min_ratio > 3.0 else SeverityLevel.MEDIUM
                
                return self._create_problem(
                    ProblemType.PERFORMANCE_DEGRADATION,
                    severity,
                    "High system load detected",
                    f"System load average {load_avg[0]:.2f} exceeds capacity (CPU count: {cpu_count})",
                    0.85,
                    {
                        "load_1min": load_avg[0],
                        "load_5min": load_avg[1],
                        "load_15min": load_avg[2],
                        "cpu_count": cpu_count,
                        "load_ratio_1min": load_1min_ratio,
                        "load_ratio_5min": load_5min_ratio
                    },
                    ["system_performance", "cpu", "scheduling"]
                )
                
        except Exception as e:
            return self._create_problem(
                ProblemType.SOFTWARE_ERROR,
                SeverityLevel.LOW,
                "Load average check failed",
                f"Unable to check system load: {str(e)}",
                0.6,
                {"error": str(e)},
                ["system_monitoring"]
            )
        
        return None


class ConfigDetector(ProblemDetector):
    """Configuration problem detector."""
    
    def __init__(self, config: Dict[str, Any]):
        super().__init__("config_detector", config)
        self.validate_syntax = config.get("validate_syntax", True)
        self.validate_integrity = config.get("validate_integrity", True)
        self.config_files = config.get("config_files", [])
        self.required_configs = config.get("required_configs", [])
    
    async def detect_problems(self, device_context: Dict[str, Any]) -> List[DetectedProblem]:
        """Detect configuration problems."""
        self.last_check_time = datetime.now()
        problems = []
        
        try:
            # Check for missing required configurations
            missing_problems = await self._check_missing_configs()
            problems.extend(missing_problems)
            
            # Validate configuration file syntax
            if self.validate_syntax:
                syntax_problems = await self._check_config_syntax()
                problems.extend(syntax_problems)
            
            # Check configuration integrity
            if self.validate_integrity:
                integrity_problem = await self._check_config_integrity()
                if integrity_problem:
                    problems.append(integrity_problem)
                    
        except Exception as e:
            error_problem = self._create_problem(
                ProblemType.CONFIGURATION_ISSUE,
                SeverityLevel.MEDIUM,
                "Configuration detector error",
                f"Error during configuration detection: {str(e)}",
                0.7,
                {"error": str(e)},
                ["config_detector"]
            )
            problems.append(error_problem)
        
        logger.debug(f"Configuration detector found {len(problems)} problems")
        return problems
    
    async def _check_missing_configs(self) -> List[DetectedProblem]:
        """Check for missing required configuration files."""
        problems = []
        
        for config_path in self.required_configs:
            try:
                import os
                if not os.path.exists(config_path):
                    problem = self._create_problem(
                        ProblemType.CONFIGURATION_ISSUE,
                        SeverityLevel.HIGH,
                        f"Missing required configuration: {config_path}",
                        f"Required configuration file '{config_path}' does not exist",
                        0.95,
                        {"config_path": config_path},
                        ["configuration", "file_system"]
                    )
                    problems.append(problem)
                    
            except Exception as e:
                problem = self._create_problem(
                    ProblemType.CONFIGURATION_ISSUE,
                    SeverityLevel.MEDIUM,
                    f"Configuration check failed: {config_path}",
                    f"Unable to check configuration file '{config_path}': {str(e)}",
                    0.7,
                    {"config_path": config_path, "error": str(e)},
                    ["configuration", "file_system"]
                )
                problems.append(problem)
        
        return problems
    
    async def _check_config_syntax(self) -> List[DetectedProblem]:
        """Check configuration file syntax."""
        problems = []
        
        for config_path in self.config_files:
            try:
                import os
                if not os.path.exists(config_path):
                    continue
                
                # Determine file type and validate accordingly
                if config_path.endswith('.json'):
                    await self._validate_json_file(config_path, problems)
                elif config_path.endswith(('.yaml', '.yml')):
                    await self._validate_yaml_file(config_path, problems)
                elif config_path.endswith('.ini'):
                    await self._validate_ini_file(config_path, problems)
                    
            except Exception as e:
                problem = self._create_problem(
                    ProblemType.CONFIGURATION_ISSUE,
                    SeverityLevel.MEDIUM,
                    f"Configuration syntax check failed: {config_path}",
                    f"Unable to validate configuration file: {str(e)}",
                    0.7,
                    {"config_path": config_path, "error": str(e)},
                    ["configuration", "syntax"]
                )
                problems.append(problem)
        
        return problems
    
    async def _validate_json_file(self, file_path: str, problems: List[DetectedProblem]):
        """Validate JSON configuration file."""
        try:
            with open(file_path, 'r') as f:
                json.load(f)
        except json.JSONDecodeError as e:
            problem = self._create_problem(
                ProblemType.CONFIGURATION_ISSUE,
                SeverityLevel.HIGH,
                f"Invalid JSON syntax: {file_path}",
                f"JSON syntax error in '{file_path}': {str(e)}",
                0.9,
                {"config_path": file_path, "json_error": str(e)},
                ["configuration", "json_syntax"]
            )
            problems.append(problem)
    
    async def _validate_yaml_file(self, file_path: str, problems: List[DetectedProblem]):
        """Validate YAML configuration file."""
        try:
            import yaml
            with open(file_path, 'r') as f:
                yaml.safe_load(f)
        except yaml.YAMLError as e:
            problem = self._create_problem(
                ProblemType.CONFIGURATION_ISSUE,
                SeverityLevel.HIGH,
                f"Invalid YAML syntax: {file_path}",
                f"YAML syntax error in '{file_path}': {str(e)}",
                0.9,
                {"config_path": file_path, "yaml_error": str(e)},
                ["configuration", "yaml_syntax"]
            )
            problems.append(problem)
        except ImportError:
            # YAML library not available
            pass
    
    async def _validate_ini_file(self, file_path: str, problems: List[DetectedProblem]):
        """Validate INI configuration file."""
        try:
            import configparser
            config = configparser.ConfigParser()
            config.read(file_path)
        except configparser.Error as e:
            problem = self._create_problem(
                ProblemType.CONFIGURATION_ISSUE,
                SeverityLevel.HIGH,
                f"Invalid INI syntax: {file_path}",
                f"INI syntax error in '{file_path}': {str(e)}",
                0.9,
                {"config_path": file_path, "ini_error": str(e)},
                ["configuration", "ini_syntax"]
            )
            problems.append(problem)
    
    async def _check_config_integrity(self) -> Optional[DetectedProblem]:
        """Check overall configuration integrity."""
        try:
            # Placeholder for configuration integrity checks
            # In a real implementation, this would check for:
            # - Conflicting settings
            # - Missing required parameters
            # - Invalid parameter values
            # - Dependency issues between configurations
            
            # For now, we'll do a simple check
            integrity_issues = []
            
            # Example check: ensure all config files are readable
            for config_path in self.config_files:
                try:
                    import os
                    if os.path.exists(config_path):
                        with open(config_path, 'r') as f:
                            f.read(1)  # Try to read first byte
                except PermissionError:
                    integrity_issues.append(f"Cannot read {config_path} (permission denied)")
                except Exception as e:
                    integrity_issues.append(f"Cannot access {config_path} ({str(e)})")
            
            if integrity_issues:
                return self._create_problem(
                    ProblemType.CONFIGURATION_ISSUE,
                    SeverityLevel.MEDIUM,
                    "Configuration integrity issues",
                    f"Found {len(integrity_issues)} configuration integrity issues",
                    0.7,
                    {
                        "integrity_issues": integrity_issues,
                        "checked_files": self.config_files
                    },
                    ["configuration", "file_permissions"]
                )
                
        except Exception as e:
            return self._create_problem(
                ProblemType.CONFIGURATION_ISSUE,
                SeverityLevel.MEDIUM,
                "Configuration integrity check failed",
                f"Unable to check configuration integrity: {str(e)}",
                0.6,
                {"error": str(e)},
                ["configuration"]
            )
        
        return None


# Example usage and testing
if __name__ == "__main__":
    import asyncio
    
    async def test_detectors():
        """Test problem detectors."""
        # Test configurations
        network_config = {
            "enabled": True,
            "check_interval": 30,
            "timeout": 5,
            "test_urls": ["https://www.google.com", "https://1.1.1.1"]
        }
        
        hardware_config = {
            "enabled": True,
            "check_interval": 60,
            "cpu_threshold": 80,
            "memory_threshold": 80,
            "disk_threshold": 85
        }
        
        # Create detectors
        network_detector = NetworkDetector(network_config)
        hardware_detector = HardwareDetector(hardware_config)
        
        detectors = [network_detector, hardware_detector]
        
        print("Testing problem detectors...")
        
        for detector in detectors:
            print(f"\nTesting {detector.name}:")
            device_context = {"device_id": "test_device_001"}
            
            problems = await detector.detect_problems(device_context)
            
            print(f"  Found {len(problems)} problems:")
            for problem in problems:
                print(f"    - {problem.title} ({problem.severity.value}) - {problem.confidence:.2f}")
    
    # Run test
    asyncio.run(test_detectors())